#pragma once
#include <string>
#include <vector>
#include "types.hpp"
#include "Utils.hpp"
#include "COperation.hpp"

class CPlayer;
class CMob;

////////////////////////////////////////////////////////////////
// CMob
//
class CField;
/// Ship（Mob）
class CMob : public CProperty<CMob, CPlayer>
{
	friend class CField; // for CField::putMob();

public:
	static Container getParent();
	CPlayer* pPlayer;
	
public:
	COperations Ops;

public:
	CMob(uint type_id, position_t position);

	uint getId() const { return id; }
	uint getType() const { return type; } ///< Get type
	int getLife() const { return life; } ///< Get life
	position_t getPos() const { return pos; } ///< Get position
	bool isDead() const { return life < 1; } /// < Is dead

	void addOperation(Operations::IOperation* newed_instance);
	bool damage(uint value);
	void remove();

	void print() const;

private:
	uint id;		///< Mob's Id
	uint type;		///< Mob's type
	int life;		///< Mob's life
	position_t pos;	///< Mob's position
};
typedef ptr_vector<CMob> CMobs;

////////////////////////////////////////////////////////////////
// CPlayer
//
/// プレイヤー
class CPlayer
{
public:
	CMobs Mobs;	///< Mobs had by player
	
public:
	CPlayer();

	void addMob(CMob* newed_instance);
	uint getId() const { return id; }
	bool isCpu() const { return iscpu; }///< Get player is CPU
	void print() const;

private:
	bool iscpu;	///< Player is cpu
	uint id;	///< ID
};

/**
* @brief プレイヤーの管理
*
* This class is core of manegement of players and its inner objects.
*
* @warning Don't delete as vector<CPlayer>.
*/
class CPlayers : public ptr_vector<CPlayer>
{
	class Impl;
	
public:
	CPlayers();
	~CPlayers();

	void addPlayer(CPlayer* newed_instance);

	void print();

public: // Proccessing collectively
	template<class T, class It, class Fn>
	void copy(It out, Fn func);
	template<class T, class It>
	void copy(It out);
//	void copy(Iterator out, Fn func = [](T& t){ return t });

	template<class T, class Fn>
	void foreach(Fn function);

private: // non-copyable
	CPlayers(const CPlayers&); // = delete
	CPlayers& operator=(const CPlayers&); // = delete
};

#include "CPlayer_impl.hpp"

